#include "unp.h"

#include <stdarg.h>
#include <syslog.h>

static void err_doit(int, int, const char *, va_list);

/*非致命的系统调用错误
 * 打印错误信息，返回*/
void
err_ret(const char *fmt, ...) {
    va_list     ap;

    va_start(ap, fmt);
    err_doit(1, LOG_INFO, fmt, ap);
    va_end(ap);
    return;
}

/*致命的系统调用错误
 * 打印错误信息，退出*/
void
err_sys(const char *fmt, ...) {
    va_list     ap;

    va_start(ap, fmt);
    err_doit(1, LOG_ERR, fmt, ap);
    va_end(ap);
    exit(1);
}

/*致命的系统调用错误
 * 打印错误信息,内核转储，退出*/
void
err_dump(const char *fmt, ...) {
    va_list     ap;

    va_start(ap, fmt);
    err_doit(1, LOG_ERR, fmt, ap);
    va_end(ap);
    abort();
    exit(1);
}

/*与系统调用无关的非致命的错误
 * 打印错误信息,返回*/
void
err_msg(const char *fmt, ...) {
    va_list     ap;

    va_start(ap, fmt);
    err_doit(0, LOG_INFO, fmt, ap);
    va_end(ap);
    return;
}


/*与系统调用无关的致命的错误
 * 打印错误信息,退出*/
void
err_quit(const char *fmt, ...) {
    va_list     ap;

    va_start(ap, fmt);
    err_doit(0, LOG_INFO, fmt, ap);
    va_end(ap);
    exit(1);
    return;
}

/*打印信息，返回到调用者
 * 调用者指定"errnoflag"和"level"*/
static void
err_doit(int errnoflag, int level, const char *fmt, va_list ap) {
    int     errno_save, n;
    char    buf[MAXLINE+1];

    errno_save = errno;
    vsnprintf(buf, MAXLINE, fmt, ap);

    n = strlen(buf);
    if (errnoflag)
        snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
    strcat(buf, "\n");
    
    fflush(stdout);
    fputs(buf, stderr);
    fflush(stderr);
    return;
}

